﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraBars;
using CTEM.Models;
using CTEM.Controllers.BUS;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;
using CTEM.Controllers.Global;
using DevExpress.XtraEditors.DXErrorProvider;
using DevExpress.XtraEditors;
using CTEM.Controllers.Global;
using DevExpress.XtraEditors.Controls;
using DevExpress.Utils;
using System.Globalization;
using DevExpress.XtraGrid.Views.Grid;

namespace CTEM.ModuleForms.ManageConstruction
{
    public partial class ConstructionProgressManagement : DevExpress.XtraBars.Ribbon.RibbonForm
    {
        private readonly ConstructionBUS _consBUS = new ConstructionBUS();
        private List<CS_ConstructionProgressDTO> _listconspro = new List<CS_ConstructionProgressDTO>();
        private readonly List<CS_ConstructionProgressDTO> _listHistory = new List<CS_ConstructionProgressDTO>();
        private bool _isNew;
        private bool _isAllowEdit;
        private CS_ConstructionDTO _cons;

        public ConstructionProgressManagement()
        {
            InitializeComponent();
        }

        public ConstructionProgressManagement(CS_ConstructionDTO cons)
        {
            InitializeComponent();
            _cons = cons;
        }

        private void ConstructionProgressManagement_Load(object sender, EventArgs e)
        {
            _isAllowEdit = true;
            AllowEditorNot();
            LoadRepositoryItems();
            LoadActiveConstructionProgress();
            Global.InitLayoutGridView(gridViewConstructionProgress);
        }

        private void barButtonItemLoadAll_ItemClick(object sender, ItemClickEventArgs e)
        {
            LoadRepositoryItems();
            LoadAllConstructionProgress();
        }

        private void barButtonItemRefresh_ItemClick(object sender, ItemClickEventArgs e)
        {
            LoadRepositoryItems();
            LoadActiveConstructionProgress();
        }

        private void barButtonItemUndo_ItemClick(object sender, ItemClickEventArgs e)
        {
            Undo();
        }

        private void barButtonItemRedo_ItemClick(object sender, ItemClickEventArgs e)
        {
            Redo();
        }

        /// <summary>
        /// Allow User can edit or not
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void barButtonItemAllowEdit_ItemClick(object sender, ItemClickEventArgs e)
        {
            AllowEditorNot();
        }

        /// <summary>
        /// Make ExceptionMode is NoAction that's to custom control action when exception thew
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gridViewConstructionProgress_InvalidRowException(object sender, InvalidRowExceptionEventArgs e)
        {
            e.ExceptionMode = ExceptionMode.NoAction;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gridViewConstructionProgress_InvalidValueException(object sender, InvalidValueExceptionEventArgs e)
        {
            e.ErrorText = Constants.INVALIDATE_VALUE;
            e.ExceptionMode = ExceptionMode.DisplayError;
        }


        private void gridViewConstructionProgress_ValidateRow(object sender, ValidateRowEventArgs e)
        {
            if (_isNew)
            {
                ColumnView view = sender as ColumnView;
                CS_ConstructionProgressDTO consDTO = e.Row as CS_ConstructionProgressDTO;
                string errorMessage;
                string fieldName;
                if (_consBUS.ValidateConstructionProgress(consDTO, out errorMessage, out fieldName))
                {
                    consDTO.ConstructionID = _cons.ConstructionID;
                    long consID = _consBUS.CreateConstructionProgress(consDTO);
                    if (consID == 0)
                    {
                        alertControlMain.Show(this, Constants.ALERT_ERROR, Constants.CREATE_FAIL);
                    }
                    else
                    {
                        alertControlMain.Show(this, Constants.CONFIRM, "Bạn Đã Tạo Mới Thành Công!");
                        RemoveRedoHistory();
                        consDTO.ConstructionProgressID = consID;
                        consDTO.History = HistoryLevel.ADD;
                        _listHistory.Add(consDTO);
                    }
                    _isNew = false;
                    LoadActiveConstructionProgress();
                }
                else
                {
                    e.Valid = false;
                    view.ClearColumnErrors();
                    view.SetColumnError(view.Columns[fieldName], errorMessage, ErrorType.Warning);
                    DialogResult result = XtraMessageBox.Show(errorMessage + "\nBạn có muốn nhập lại thông tin", Constants.CONFIRM, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (result == DialogResult.No)
                    {
                        _isNew = false;
                        e.Valid = true;
                        LoadActiveConstructionProgress();
                    }
                    else
                    {
                        view.FocusedColumn = view.Columns[fieldName];
                    }
                }
            }
            else
            {
                LoadActiveConstructionProgress();
            }
        }

        /// <summary>
        /// Using to edit a ConstructionProgress
        /// </summary>
        /// <param name="sender">ColumhView</param>
        /// <param name="e">CellValue changed event argurements</param>
        private void gridViewConstructionProgress_CellValueChanged(object sender, CellValueChangedEventArgs e)
        {
            if (!_isNew)
            {
                ColumnView view = sender as ColumnView;
                int currentRow = e.RowHandle;
                CS_ConstructionProgressDTO estDTO = gridViewConstructionProgress.GetRow(currentRow) as CS_ConstructionProgressDTO;
                CS_ConstructionProgressDTO backupEst = _consBUS.GetConstructionProgressByID(estDTO.ConstructionID);
                bool success = _consBUS.UpdateConstructionProgress(estDTO);
                if (!success)
                {
                    alertControlMain.Show(this, Constants.ALERT_ERROR, Constants.UPDATE_FAIL);
                }
                else
                {
                    alertControlMain.Show(this, Constants.CONFIRM, "Bạn Đã Cập Nhật Thông Tin Thành Công!");
                    RemoveRedoHistory();
                    backupEst.History = HistoryLevel.EDIT;
                    _listHistory.Add(backupEst);
                }
                _isNew = false;
                LoadActiveConstructionProgress();
            }
        }

        /// <summary>
        /// Allow User Edit Data
        /// </summary>
        private void AllowEditorNot()
        {
            if (_isAllowEdit)
            {
                alertControlMain.Show(this, Constants.CONFIRM, Constants.DISABLE_EIT_MESSAGE);
                _isAllowEdit = false;
                gridViewConstructionProgress.OptionsBehavior.Editable = false;
                barButtonItemAllowEdit.Caption = Constants.ALLOW_EIT;
            }
            else
            {
                DialogResult result = XtraMessageBox.Show(Constants.ALLOW_EIT_MESSAGE, Constants.CONFIRM, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                {
                    _isAllowEdit = true;
                    gridViewConstructionProgress.OptionsBehavior.Editable = true;
                    barButtonItemAllowEdit.Caption = Constants.DISABLE_EIT;
                }
            }
        }

        /// <summary>
        /// Load Data for Reporsity Items
        /// </summary>
        private void LoadRepositoryItems()
        {
            ConstructionBUS consBUS = new ConstructionBUS();
            //cSConstructionDTOBindingSource.DataSource = consBUS.LoadConstruction(false);
        }

        /// <summary>
        /// Load active ConstructionProgresss
        /// </summary>
        private void LoadActiveConstructionProgress()
        {
            LoadConstructionProgress(true);
        }

        /// <summary>
        /// Load both active and inactive ConstructionProgresss
        /// </summary>
        private void LoadAllConstructionProgress()
        {
            LoadConstructionProgress(false);
        }

        /// <summary>
        /// Function is called to load constructions
        /// </summary>
        /// <param name="isactive">Load all construction or just active construction</param>
        private void LoadConstructionProgress(bool isactive)
        {
            _listconspro = _consBUS.LoadConstructionProgress(_cons.ConstructionID);
            cSConstructionProgressDTOBindingSource.DataSource = _listconspro;
        }

        /// <summary>
        /// After undo, item will change status to waiting for redo.
        /// But after new action work, all items wating for redo must be remove
        /// </summary>
        private void RemoveRedoHistory()
        {
            for (int i = 0; i < _listHistory.Count; i++)
            {
                var cons = _listHistory[i];
                if (cons.History.ToString().Contains(Constants.UNDO))
                {
                    _listHistory.Remove(cons);
                    i--;
                }
            }
        }

        /// <summary>
        /// Undo user action
        /// </summary>
        private void Undo()
        {
            int numHistoryItems = _listHistory.Count;
            for (int i = numHistoryItems; i > 0; i--)
            {
                var undoItem = _listHistory[i - 1];
                switch (undoItem.History)
                {
                    case HistoryLevel.ADD:
                        break;
                    case HistoryLevel.EDIT:
                        _listHistory[i - 1] = _consBUS.GetConstructionProgressByID(undoItem.ConstructionID);
                        _listHistory[i - 1].History = HistoryLevel.UNDO_EDIT;
                        _consBUS.UpdateConstructionProgress(undoItem);
                        LoadActiveConstructionProgress();
                        return;
                    case HistoryLevel.DELETE:
                        break;
                    case HistoryLevel.UNDO_ADD:
                        break;
                    case HistoryLevel.UNDO_EDIT:
                        break;
                    case HistoryLevel.UNDO_DELETE:
                        break;
                }
            }
        }

        /// <summary>
        /// Redo user action
        /// </summary>
        private void Redo()
        {
            int numHistoryItems = _listHistory.Count;
            for (int i = 0; i < numHistoryItems; i++)
            {
                var redoItem = _listHistory[i];
                switch (redoItem.History)
                {
                    case HistoryLevel.ADD:
                        break;
                    case HistoryLevel.EDIT:
                        break;
                    case HistoryLevel.DELETE:
                        break; ;
                    case HistoryLevel.UNDO_ADD:
                        break;
                    case HistoryLevel.UNDO_EDIT:
                        _listHistory[i] = _consBUS.GetConstructionProgressByID(redoItem.ConstructionID);
                        _listHistory[i].History = HistoryLevel.EDIT;
                        _consBUS.UpdateConstructionProgress(redoItem);
                        LoadActiveConstructionProgress();
                        return;
                    case HistoryLevel.UNDO_DELETE:
                        break;
                }
            }
        }

        private void gridViewConstructionProgress_FocusedRowChanged(object sender, FocusedRowChangedEventArgs e)
        {
            if (e.FocusedRowHandle == GridControl.NewItemRowHandle)
            {
                gridViewConstructionProgress.OptionsBehavior.ReadOnly = false;
            }
            else
            {
                if (_isAllowEdit)
                {
                    barButtonItemAllowEdit_ItemClick(null, null);
                }
            }
        }

        private void DeleteConstructionProgress()
        {
            int[] numOfSelectedRows = gridViewConstructionProgress.GetSelectedRows();
            if (numOfSelectedRows.Length > 0)
            {
                CS_ConstructionProgressDTO consproDTO = gridViewConstructionProgress.GetRow(numOfSelectedRows[0]) as CS_ConstructionProgressDTO;
                DialogResult result = XtraMessageBox.Show("Bạn Có Chắc Muốn Không?", Constants.ALERT, MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (result == DialogResult.Yes)
                {
                    CS_ConstructionProgressDTO backupConspro = _consBUS.GetConstructionProgressByID(consproDTO.ConstructionProgressID);
                    consproDTO.IsDelete = true;
                    bool success = _consBUS.UpdateConstructionProgress(consproDTO);
                    if (!success)
                    {
                        alertControlMain.Show(this, Constants.ALERT_ERROR, "Không Thể Xóa Thành Công");
                    }
                    else
                    {
                        alertControlMain.Show(this, Constants.CONFIRM, "Bạn Đã Xóa Thành Công");
                        RemoveRedoHistory();
                        backupConspro.History = HistoryLevel.EDIT;
                        _listHistory.Add(backupConspro);
                    }
                }
            }
            LoadActiveConstructionProgress();
        }

        private void barButtonItemDelete_ItemClick(object sender, ItemClickEventArgs e)
        {
            DeleteConstructionProgress();
        }

        private void gridViewConstructionProgress_InitNewRow(object sender, InitNewRowEventArgs e)
        {
            _isNew = true;
        }
    }
}